package com.hopes.bizz.poll.om.logic;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.hopes.bizz.common.core.util.NumberUtil;
import com.hopes.bizz.poll.om.entity.BaseOmDataEntity;
import lombok.Data;

import java.util.*;

import static com.hopes.bizz.poll.hj212.constant.HJ212Constant.*;

/**
 * @author daijie
 * @version 1.0
 * @date 2023/10/10 11:34
 * @Description:
 */
@Data
public class MonitorDataStatisticLogic {
    private Long monitorSiteId;

    private Map<String, List<JSONObject>> dataMap = new HashMap<>();

    /**
     * 添加监测数据
     *
     * @param key
     * @param dataItem
     */
    public void add(String key, JSONObject dataItem) {
        List<JSONObject> valueList = dataMap.get(key);
        if (valueList == null) {
            valueList = new ArrayList<>();
            dataMap.put(key, valueList);
        }
        valueList.add(dataItem);
    }

    public JSONObject buildStatisticDataJson() {
        JSONObject dataJson = new JSONObject();
        for (String key : dataMap.keySet()) {
            List<JSONObject> valueList = dataMap.get(key);
            Map<String, List<Object>> valueMap = new HashMap<>();
            if (CollectionUtil.isNotEmpty(valueList)) {
                JSONObject firstObj = valueList.get(0);
                Set<String> keySet = firstObj.keySet();

                for (JSONObject valueObj : valueList) {
                    for (String dataAttrKey : keySet) {
                        addValueItem(dataAttrKey, valueObj.get(dataAttrKey), valueMap);
                    }
                }

                JSONObject dataItem = new JSONObject();
                dataJson.put(key, dataItem);
                calculateAndSetAttrValue(dataItem, keySet, valueMap);


            }

        }
        return dataJson;
    }

    /**
     * 计算属性值并设置到对象中
     *
     * @param dataItem
     * @param keySet
     * @param valueMap
     */
    private void calculateAndSetAttrValue(JSONObject dataItem, Set<String> keySet, Map<String, List<Object>> valueMap) {
        String avgKey = null;
        String zsAvgKey = null;
        for (String dataAttrKey : keySet) {
            if (dataAttrKey.equalsIgnoreCase(DATA_ITEM_ATTR_VALUE)) {
                avgKey = dataAttrKey;
            }

            if (dataAttrKey.equalsIgnoreCase(DATA_ITEM_ATTR_ZS_VALUE)) {
                zsAvgKey = dataAttrKey;
            }
        }
        for (String dataAttrKey : keySet) {
            Object value = null;
            // 均值: 只要包含 avg 就计算对应的均值
            if (dataAttrKey.toLowerCase().contains(DATA_ITEM_ATTR_VALUE)) {
                value = getAvgValue(dataAttrKey, valueMap);
            } else if (dataAttrKey.toLowerCase().contains(LOWER_DATA_ITEM_ATTR_MAX)) {
                value = getMaxValue(dataAttrKey, avgKey, zsAvgKey, valueMap);
            } else if (dataAttrKey.toLowerCase().contains(LOWER_DATA_ITEM_ATTR_MIN)) {
                value = getMinValue(dataAttrKey, avgKey, zsAvgKey, valueMap);
            } else if (dataAttrKey.toLowerCase().contains(LOWER_DATA_ITEM_ATTR_COU)) {
                value = getCouValue(dataAttrKey, valueMap);
            } else if (dataAttrKey.toLowerCase().contains(DATA_ITEM_ATTR_KEY)) {
                value = valueMap.get(dataAttrKey).get(0);
            }
            dataItem.put(dataAttrKey, value);
        }
    }

    /**
     * 获取累计值
     *
     * @param dataAttrKey
     * @param valueMap
     * @return
     */
    private Object getCouValue(String dataAttrKey, Map<String, List<Object>> valueMap) {
        List<Object> valueObjectList = valueMap.get(dataAttrKey);
        Double sum = 0d;
        Double tempData = null;
        for (Object json : valueObjectList) {
            if (json != null) {
                tempData = Double.valueOf(json.toString());
                sum += tempData;
            }
        }
        return NumberUtil.toScaledDouble(sum, 4);
    }

    /**
     * 获取最小
     *
     * @param dataAttrKey
     * @param valueMap
     * @return
     */
    private Object getMinValue(String dataAttrKey, String avgKey, String zsAvgKey, Map<String, List<Object>> valueMap) {
        String key = dataAttrKey.toLowerCase().contains(DATA_ITEM_ATTR_TYPE_ZS) ? zsAvgKey : avgKey;

        List<Object> valueObjectList = valueMap.get(key);
        if (CollectionUtil.isNotEmpty(valueObjectList)) {
            Double min = null;
            Double tempData = null;
            for (Object json : valueObjectList) {
                if (json != null) {
                    tempData = Double.valueOf(json.toString());
                    if (tempData != null && (min == null || tempData < min)) {
                        min = tempData;
                    }
                }
            }
            return min;
        }
        return null;
    }

    /**
     * 获取最大值
     *
     * @param dataAttrKey
     * @param valueMap
     * @return
     */
    private Object getMaxValue(String dataAttrKey, String avgKey, String zsAvgKey, Map<String, List<Object>> valueMap) {
        String key = dataAttrKey.toLowerCase().contains(DATA_ITEM_ATTR_TYPE_ZS) ? zsAvgKey : avgKey;

        List<Object> valueObjectList = valueMap.get(key);
        if (CollectionUtil.isNotEmpty(valueObjectList)) {
            Double max = null;
            Double tempData = null;
            for (Object json : valueObjectList) {
                if (json != null) {
                    tempData = Double.valueOf(json.toString());
                    if (tempData != null && (max == null || tempData > max)) {
                        max = tempData;
                    }
                }
            }
            return max;
        }
        return null;
    }

    /**
     * 获取均值
     *
     * @param dataAttrKey
     * @param valueMap
     * @return
     */
    private Double getAvgValue(String dataAttrKey, Map<String, List<Object>> valueMap) {
        List<Object> valueObjectList = valueMap.get(dataAttrKey);
        int count = 0;
        Double sum = 0d;
        Double tempData = null;
        for (Object json : valueObjectList) {
            if (json != null) {
                tempData = Double.valueOf(json.toString());
                sum += tempData;
                count++;
            }
        }
        if (count > 0) {
            return NumberUtil.toScaledDouble(sum / count, 4);
        }
        return null;
    }

    private void addValueItem(String dataAttrKey, Object obj, Map<String, List<Object>> valueMap) {
        List<Object> list = valueMap.get(dataAttrKey);
        if (list == null) {
            list = new ArrayList<>();
            valueMap.put(dataAttrKey, list);
        }
        list.add(obj);
    }


    /**
     * 统计监测数据
     *
     * @param dataTime            数据时间
     * @param srcDataList         原数据
     * @return 统计数据列表
     */
    public static List<BaseOmDataEntity> doStatistic(Date dataTime, List<? extends BaseOmDataEntity> srcDataList) {
        List<BaseOmDataEntity> dataList = new ArrayList<>();
        Map<Long, BaseOmDataEntity> tempCompanyDataMap = new HashMap<>();
        BaseOmDataEntity entity;
        MonitorDataStatisticLogic statisticLogic = null;
        if (CollectionUtil.isNotEmpty(srcDataList)) {
            for (BaseOmDataEntity omDataEntity : srcDataList) {

                entity = tempCompanyDataMap.get(omDataEntity.getMonitorSiteId());
                if (entity == null) {
                    entity = new BaseOmDataEntity();
                    entity.setMonitorSiteId(omDataEntity.getMonitorSiteId());
                    entity.setDataTime(dataTime);
                    tempCompanyDataMap.put(omDataEntity.getMonitorSiteId(), entity);
                    dataList.add(entity);
                    if (statisticLogic != null) {
                        JSONObject dataJson = statisticLogic.buildStatisticDataJson();
                        tempCompanyDataMap.get(statisticLogic.getMonitorSiteId()).setDataJson(dataJson);
                    }

                    statisticLogic = new MonitorDataStatisticLogic();
                    statisticLogic.setMonitorSiteId(omDataEntity.getMonitorSiteId());
//                    statisticLogic.setAddUpVo(getCompanyAddUpVo(omDataEntity.getMonitorSiteId(), addUpList));
                }
                JSONObject dataJson = omDataEntity.getDataJson();
                JSONObject dataItem = null;
                if (dataJson != null) {
                    Set<String> keySet = dataJson.keySet();
                    for (String key : keySet) {
                        dataItem = dataJson.getJSONObject(key);
                        if (dataItem != null) {
                            statisticLogic.add(key, dataItem);
                        }
                    }
                }
            }
            if (statisticLogic != null) {
                JSONObject dataJson = statisticLogic.buildStatisticDataJson();
                tempCompanyDataMap.get(statisticLogic.getMonitorSiteId()).setDataJson(dataJson);
            }
        }

        return dataList;
    }
}

